home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
MNetsrc.hqx
/
Mac TCP_IP Source v.33
/
ax25dump.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-22
|
11KB
|
453 lines
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "lapb.h"
#include "trace.h"
#ifdef MAC
extern int tcptrcflg;
extern FILE *trcwndp;
#endif
/* Dump an AX.25 packet header */
ax25_dump(bpp,check)
struct mbuf **bpp;
int check; /* Not used */
{
char *decode_type();
char tmp[20];
char control,pid;
int16 type,ftype();
struct ax25 hdr;
struct ax25_addr *hp;
#ifdef MAC
fprintf(trcwndp,"AX25: ");
#else
printf("AX25: ");
#endif
/* Extract the address header */
if(ntohax25(&hdr,bpp) < 0){
/* Something wrong with the header */
#ifdef MAC
fprintf(trcwndp," bad header!\n");
#else
printf(" bad header!\n");
#endif
return;
}
#ifdef MAC
pax25(tmp,&hdr.source);
fprintf(trcwndp,"%s",tmp);
pax25(tmp,&hdr.dest);
fprintf(trcwndp,"->%s",tmp);
if(hdr.ndigis > 0){
fprintf(trcwndp," v");
for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
/* Print digi string */
pax25(tmp,hp);
fprintf(trcwndp," %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
#else
pax25(tmp,&hdr.source);
printf("%s",tmp);
pax25(tmp,&hdr.dest);
printf("->%s",tmp);
if(hdr.ndigis > 0){
printf(" v");
for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
/* Print digi string */
pax25(tmp,hp);
printf(" %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
#endif
}
}
if(pullup(bpp,&control,1) != 1)
return;
#ifdef MAC
fputc(' ',trcwndp);
type = ftype(control);
fprintf(trcwndp,"%s",decode_type(type));
/* Dump poll/final bit */
if(control & PF){
switch(hdr.cmdrsp){
case COMMAND:
fprintf(trcwndp,"(P)");
break;
case RESPONSE:
fprintf(trcwndp,"(F)");
break;
default:
fprintf(trcwndp,"(P/F)");
break;
#else
putchar(' ');
type = ftype(control);
printf("%s",decode_type(type));
/* Dump poll/final bit */
if(control & PF){
switch(hdr.cmdrsp){
case COMMAND:
printf("(P)");
break;
case RESPONSE:
printf("(F)");
break;
default:
printf("(P/F)");
break;
#endif
}
}
/* Dump sequence numbers */
#ifdef MAC
if((type & 0x3) != U) /* I or S frame? */
fprintf(trcwndp," NR=%d",(control>>5)&7);
if(type == I || type == UI){
if(type == I)
fprintf(trcwndp," NS=%d",(control>>1)&7);
/* Decode I field */
if(pullup(bpp,&pid,1) == 1){ /* Get pid */
switch(pid & (PID_FIRST | PID_LAST)){
case PID_FIRST:
fprintf(trcwndp," First frag");
break;
case PID_LAST:
fprintf(trcwndp," Last frag");
break;
case PID_FIRST|PID_LAST:
break; /* Complete message, say nothing */
case 0:
fprintf(trcwndp," Middle frag");
break;
}
fprintf(trcwndp," pid=");
switch(pid & 0x3f){
case PID_ARP:
fprintf(trcwndp,"ARP\n");
break;
case PID_NETROM:
fprintf(trcwndp,"NET/ROM\n");
break;
case PID_IP:
fprintf(trcwndp,"IP\n");
break;
case PID_NO_L3:
fprintf(trcwndp,"Text\n");
break;
default:
fprintf(trcwndp,"0x%x\n",pid);
#else
if((type & 0x3) != U) /* I or S frame? */
printf(" NR=%d",(control>>5)&7);
if(type == I || type == UI){
if(type == I)
printf(" NS=%d",(control>>1)&7);
/* Decode I field */
if(pullup(bpp,&pid,1) == 1){ /* Get pid */
switch(pid & (PID_FIRST | PID_LAST)){
case PID_FIRST:
printf(" First frag");
break;
case PID_LAST:
printf(" Last frag");
break;
case PID_FIRST|PID_LAST:
break; /* Complete message, say nothing */
case 0:
printf(" Middle frag");
break;
}
printf(" pid=");
switch(pid & 0x3f){
case PID_ARP:
printf("ARP\n");
break;
case PID_NETROM:
printf("NET/ROM\n");
break;
case PID_IP:
printf("IP\n");
break;
case PID_NO_L3:
printf("Text\n");
break;
default:
printf("0x%x\n",pid);
#endif
}
/* Only decode frames that are the first in a
* multi-frame sequence
*/
switch(pid & (PID_PID | PID_FIRST)){
case PID_ARP | PID_FIRST:
arp_dump(bpp);
break;
case PID_IP | PID_FIRST:
/* Only checksum complete frames */
ip_dump(bpp,pid & PID_LAST);
break;
case PID_NETROM | PID_FIRST:
netrom_dump(bpp);
break;
}
}
} else if(type == FRMR && pullup(bpp,tmp,3) == 3){
#ifdef MAC
fprintf(trcwndp,": %s",decode_type(ftype(tmp[0])));
fprintf(trcwndp," Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
(tmp[1] >> 1) & MMASK);
if(tmp[2] & W)
fprintf(trcwndp," Invalid control field");
if(tmp[2] & X)
fprintf(trcwndp," Illegal I-field");
if(tmp[2] & Y)
fprintf(trcwndp," Too-long I-field");
if(tmp[2] & Z)
fprintf(trcwndp," Invalid seq number");
fprintf(trcwndp,"\n");
} else
fprintf(trcwndp,"\n");
fflush(trcwndp);
#else
printf(": %s",decode_type(ftype(tmp[0])));
printf(" Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
(tmp[1] >> 1) & MMASK);
if(tmp[2] & W)
printf(" Invalid control field");
if(tmp[2] & X)
printf(" Illegal I-field");
if(tmp[2] & Y)
printf(" Too-long I-field");
if(tmp[2] & Z)
printf(" Invalid seq number");
printf("\n");
} else
printf("\n");
fflush(stdout);
#endif
}
/* Display NET/ROM network and transport headers */
static
netrom_dump(bpp)
struct mbuf **bpp;
{
struct ax25_addr src,dest;
char x;
char tmp[16];
char thdr[5];
register i;
if(bpp == NULLBUFP || *bpp == NULLBUF)
return;
/* See if it is a routing broadcast */
if(uchar(*(*bpp)->data) == 0xff) {
pullup(bpp,tmp,1); /* Signature */
pullup(bpp,tmp,ALEN);
tmp[ALEN] = '\0';
#ifdef MAC
fprintf(trcwndp,"NET/ROM Routing: %s\n",tmp);
for(i = 0;i < 11;i++) {
if (pullup(bpp,tmp,AXALEN) < AXALEN)
break;
memcpy(src.call,tmp,ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
fprintf(trcwndp," %12s",tmp);
pullup(bpp,tmp,ALEN);
tmp[ALEN] = '\0';
fprintf(trcwndp,"%8s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(src.call,tmp, ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
fprintf(trcwndp," %12s", tmp);
pullup(bpp,tmp,1);
fprintf(trcwndp," %3u\n", (unsigned)uchar(tmp[0]));
#else
printf("NET/ROM Routing: %s\n",tmp);
for(i = 0;i < 11;i++) {
if (pullup(bpp,tmp,AXALEN) < AXALEN)
break;
memcpy(src.call,tmp,ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
printf(" %12s",tmp);
pullup(bpp,tmp,ALEN);
tmp[ALEN] = '\0';
printf("%8s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(src.call,tmp, ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
printf(" %12s", tmp);
pullup(bpp,tmp,1);
printf(" %3u\n", (unsigned)uchar(tmp[0]));
#endif
}
return;
}
/* Decode network layer */
pullup(bpp,tmp,AXALEN);
memcpy(src.call,tmp,ALEN);
src.ssid = tmp[ALEN];
pax25(tmp,&src);
#ifdef MAC
fprintf(trcwndp,"NET/ROM: %s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(dest.call,tmp,ALEN);
dest.ssid = tmp[ALEN];
pax25(tmp,&dest);
fprintf(trcwndp,"->%s",tmp);
pullup(bpp,&x,1);
fprintf(trcwndp," ttl %d\n",uchar(x));
#else
printf("NET/ROM: %s",tmp);
pullup(bpp,tmp,AXALEN);
memcpy(dest.call,tmp,ALEN);
dest.ssid = tmp[ALEN];
pax25(tmp,&dest);
printf("->%s",tmp);
pullup(bpp,&x,1);
printf(" ttl %d\n",uchar(x));
#endif
/* Read first five bytes of "transport" header */
pullup(bpp,thdr,5);
switch(thdr[4] & 0xf){
case 0: /* network PID extension */
if (thdr[0] == PID_IP && thdr[1] == PID_IP)
ip_dump(bpp,1) ;
else
#ifdef MAC
fprintf(trcwndp," protocol family %x, proto %x",
uchar(thdr[0]), uchar(thdr[1])) ;
break ;
case 1: /* Connect request */
fprintf(trcwndp," conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
pullup(bpp,&x,1);
fprintf(trcwndp," wnd %d",x);
pullup(bpp,(char *)&src,sizeof(struct ax25_addr));
pax25(tmp,&src);
fprintf(trcwndp," %s",tmp);
pullup(bpp,(char *)&dest,sizeof(struct ax25_addr));
pax25(tmp,&dest);
fprintf(trcwndp,"->%s",tmp);
break;
case 2: /* Connect acknowledgement */
fprintf(trcwndp," conn ack: ur ckt %d/%d my ckt %d/%d",
uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
uchar(thdr[3]));
pullup(bpp,&x,1);
fprintf(trcwndp," wnd %d",x);
break;
case 3: /* Disconnect request */
fprintf(trcwndp," disc: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 4: /* Disconnect acknowledgement */
fprintf(trcwndp," disc ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 5: /* Information (data) */
fprintf(trcwndp," info: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
fprintf(trcwndp," txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
break;
case 6: /* Information acknowledgement */
fprintf(trcwndp," info ack: ckt %d/%d rxseq %d",
uchar(thdr[0]),uchar(thdr[1]),uchar(thdr[3]));
break;
default:
fprintf(trcwndp," unknown transport type %d", thdr[4] & 0x0f) ;
break;
}
if(thdr[4] & 0x80)
fprintf(trcwndp," CHOKE");
if(thdr[4] & 0x40)
fprintf(trcwndp," NAK");
fprintf(trcwndp,"\n");
#else
printf(" protocol family %x, proto %x",
uchar(thdr[0]), uchar(thdr[1])) ;
break ;
case 1: /* Connect request */
printf(" conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
pullup(bpp,&x,1);
printf(" wnd %d",x);
pullup(bpp,(char *)&src,sizeof(struct ax25_addr));
pax25(tmp,&src);
printf(" %s",tmp);
pullup(bpp,(char *)&dest,sizeof(struct ax25_addr));
pax25(tmp,&dest);
printf("->%s",tmp);
break;
case 2: /* Connect acknowledgement */
printf(" conn ack: ur ckt %d/%d my ckt %d/%d",
uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
uchar(thdr[3]));
pullup(bpp,&x,1);
printf(" wnd %d",x);
break;
case 3: /* Disconnect request */
printf(" disc: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 4: /* Disconnect acknowledgement */
printf(" disc ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
break;
case 5: /* Information (data) */
printf(" info: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
printf(" txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
break;
case 6: /* Information acknowledgement */
printf(" info ack: ckt %d/%d rxseq %d",
uchar(thdr[0]),uchar(thdr[1]),uchar(thdr[3]));
break;
default:
printf(" unknown transport type %d", thdr[4] & 0x0f) ;
break;
}
if(thdr[4] & 0x80)
printf(" CHOKE");
if(thdr[4] & 0x40)
printf(" NAK");
printf("\n");
#endif
}
char *
decode_type(type)
int16 type;
{
switch(uchar(type)){
case I:
return "I";
case SABM:
return "SABM";
case DISC:
return "DISC";
case DM:
return "DM";
case UA:
return "UA";
case RR:
return "RR";
case RNR:
return "RNR";
case REJ:
return "REJ";
case FRMR:
return "FRMR";
case UI:
return "UI";
default:
return "[invalid]";
}
}